﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LuaInterface;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.ServiceProcess;

namespace PrgMonitor
{
	public partial class UIFormNotify : Form
	{
		[DllImport("user32.dll")]
		public static extern IntPtr GetForegroundWindow();
		[DllImport("user32.dll")]
		public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
		[DllImport("user32.dll")]
		public static extern int GetWindow(IntPtr hWnd, int wCmd);
		[DllImport("user32.dll")]
		public static extern int GetWindowTextLength(IntPtr hWnd);
		[DllImport("user32.dll")]
		public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int nMaxCount);

		/// <summary>
		/// lua虚拟机
		/// </summary>
		private static Lua luaVM = null;

		FileSystemWatcher watcher;
		private bool bIsReLoadLua = false;

		//定时器
		System.Timers.Timer tmAutoChk;
	
		public UIFormNotify()
		{
			InitializeComponent();
		}

		private void UIFormNotify_Load(object sender, EventArgs e)
		{
			this.Hide();

			LuaInit();	//lua脚本初始化

			this.tmAutoChk = new System.Timers.Timer(10000);
			this.tmAutoChk.Elapsed += new System.Timers.ElapsedEventHandler(tmAutoChkEvent);
			this.tmAutoChk.Enabled = true;
		}


		/// <summary>
		/// lua初始化
		/// </summary>
		private void LuaInit()
		{
			try
			{
				Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

				luaVM = new Lua();

				////为脚本提供操作 byte 的方法
				//luaVM.RegisterFunction("luaGetByteValue", null, typeof(CByteOpt).GetMethod("GetByteValue"));
				//luaVM.RegisterFunction("luaSetByteValue", null, typeof(CByteOpt).GetMethod("SetByteValue"));

				////为脚本提供操作 CClientInfo 的方法
				luaVM.RegisterFunction("luaSkillProcessesByName", null, typeof(UIFormNotify).GetMethod("luaSkillProcessesByName"));
				luaVM.RegisterFunction("luaSkillProcessesById", null, typeof(UIFormNotify).GetMethod("luaSkillProcessesById"));
				luaVM.RegisterFunction("luaSkillProcessesByWnd", null, typeof(UIFormNotify).GetMethod("luaSkillProcessesByWnd"));
				luaVM.RegisterFunction("luaGetProcesseNumByName", null, typeof(UIFormNotify).GetMethod("luaGetProcesseNumByName"));
				luaVM.RegisterFunction("luaGetForegroundWindowText", null, typeof(UIFormNotify).GetMethod("luaGetForegroundWindowText"));
				luaVM.RegisterFunction("luaProcessIsForegroundWindow", null, typeof(UIFormNotify).GetMethod("luaProcessIsForegroundWindow"));
				luaVM.RegisterFunction("luaStopServiceByName", null, typeof(UIFormNotify).GetMethod("luaStopServiceByName"));

				luaVM.RegisterFunction("luaGetForegroundWindow", null, typeof(UIFormNotify).GetMethod("luaGetForegroundWindow"));
				luaVM.RegisterFunction("luaGetWindow", null, typeof(UIFormNotify).GetMethod("luaGetWindow"));
				luaVM.RegisterFunction("luaGetWindowText", null, typeof(UIFormNotify).GetMethod("luaGetWindowText"));

				//luaVM.RegisterFunction("luaClientInfoClientName", null, typeof(CClientInfo).GetMethod("luaClientName"));
				//luaVM.RegisterFunction("luaClientInfoRemotePort", null, typeof(CClientInfo).GetMethod("luaRemotePort"));
				//luaVM.RegisterFunction("luaClientInfoLocalPort", null, typeof(CClientInfo).GetMethod("luaLocalPort"));
				//luaVM.RegisterFunction("luaClientInfoClientHandle", null, typeof(CClientInfo).GetMethod("luaClientHandle"));

				if (File.Exists("lua/timeruser.lua"))
				{
					luaVM.DoFile("lua/timeruser.lua");
				}

				//监视lua目录
				watcher = new FileSystemWatcher();
				watcher.Path = "lua";
				watcher.NotifyFilter = NotifyFilters.LastWrite;
				watcher.Filter = "*.lua";
				watcher.Changed += new FileSystemEventHandler(OnLuaChanged);

				watcher.EnableRaisingEvents = true;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " LuaInit " + ex.Message);
			}
		}

		private void OnLuaChanged(object source, FileSystemEventArgs e)
		{
			//LogAPI.WriteLog(String.Format("LuaChanged：{0} {1}！", e.FullPath, e.ChangeType));
			this.bIsReLoadLua = true;
		}

		/// <summary>
		/// 自动检查定时器
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tmAutoChkEvent(object sender, System.Timers.ElapsedEventArgs e)
		{
			this.tmAutoChk.Enabled = false;
			//重载脚本
			if (this.bIsReLoadLua)
			{
				this.bIsReLoadLua = false;
				LogAPI.WriteLog("脚本变化，重新加载");
				try
				{
					if (File.Exists("lua/timeruser.lua"))
					{
						luaVM.DoFile("lua/timeruser.lua");	//处理的脚本
					}
				}
				catch (Exception ex)
				{
					LogAPI.WriteLog(ex.Source + " tmAutoChkEvent.LuaLoadFile " + ex.Message);
				}
			}

			try
			{
				LuaFunction luaFun = null;
				luaFun = luaVM.GetFunction("luaOnTimer");
				if (luaFun != null)
				{
					lock (luaVM)
					{
						try
						{
							object[] retVals = luaFun.Call();
						}
						catch (Exception ex)
						{
							LogAPI.WriteLog(ex.Source + " tmAutoChkEvent.ExecLua " + ex.Message);
						}
					}
				}
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " tmAutoChkEvent.GetFunction " + ex.Message);
			}

			this.tmAutoChk.Enabled = true;
		}


		private static Process FindProcessesByName(string sProcessName)
		{
			try
			{
				Process[] ps = Process.GetProcesses();
				foreach (Process item in ps)
				{
					if (item.ProcessName == sProcessName)
					{
						return item;
					}
				}
				return null;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " FindProcessesByName " + ex.Message);
				return null;
			}
		}

		private static Process FindProcessesById(int iProcessId)
		{
			try
			{
				Process[] ps = Process.GetProcesses();
				foreach (Process item in ps)
				{
					if (item.Id == iProcessId)
					{
						return item;
					}
				}
				return null;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " FindProcessesById " + ex.Message);
				return null;
			}
		}


		/// <summary>
		/// 提供给脚本，结束进程
		/// </summary>
		/// <param name="sProcessName"></param>
		/// <returns></returns>
		public static bool luaSkillProcessesByName(string sProcessName)
		{
			try
			{
				Process item = FindProcessesByName(sProcessName);
				if (item != null)
				{
					item.Kill();
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaSkillProcessesByName " + ex.Message);
				return false;
			}
		}

		public static bool luaSkillProcessesById(int iProcessId)
		{
			try
			{
				Process item = FindProcessesById(iProcessId);
				if (item != null)
				{
					item.Kill();
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaSkillProcessesById " + ex.Message);
				return false;
			}
		}

		public static bool luaSkillProcessesByWnd(IntPtr hwnd)
		{
			try
			{
				int iProcessId;
				GetWindowThreadProcessId(hwnd, out iProcessId);

				return luaSkillProcessesById(iProcessId);
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaSkillProcessesByWnd " + ex.Message);
				return false;
			}
		}

		/// <summary>
		/// 根据进程名字获得进程数量
		/// </summary>
		/// <param name="sProcessName"></param>
		/// <returns></returns>
		public static int luaGetProcesseNumByName(string sProcessName)
		{
			try
			{
				int iNum = 0;
				Process[] ps = Process.GetProcesses();
				foreach (Process item in ps)
				{
					if (item.ProcessName == sProcessName)
					{
						iNum++;
					}
				}
				return iNum;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaGetProcesseNumByName " + ex.Message);
				return 0;
			}
		}

		/// <summary>
		/// 获得最前窗口的名字
		/// </summary>
		/// <returns></returns>
		public static string luaGetForegroundWindowText()
		{
			IntPtr foreHwnd = GetForegroundWindow();
			if (foreHwnd != IntPtr.Zero)
			{
				int length = GetWindowTextLength(foreHwnd);
				StringBuilder windowName = new StringBuilder(length + 1);
				GetWindowText(foreHwnd, windowName, windowName.Capacity);

				return windowName.ToString();
			}
			return "";
		}

		/// <summary>
		/// 是否进程窗口在前
		/// </summary>
		/// <param name="sProcessName"></param>
		/// <returns></returns>
		public static bool luaProcessIsForegroundWindow(string sProcessName)
		{
			try
			{
				Process item = FindProcessesByName(sProcessName);
				if (item != null)
				{
					IntPtr foreHwnd = GetForegroundWindow();
					if (foreHwnd != IntPtr.Zero)
					{
						int iProcessId;
						GetWindowThreadProcessId(foreHwnd, out iProcessId);
						if (item.Id == iProcessId)
						{
							return true;
						}
					}
				}
				return false;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaProcessIsForegroundWindow " + ex.Message);
				return false;
			}
		}

		/// <summary>
		/// 停止指定的服务
		/// </summary>
		/// <param name="sServiceName"></param>
		public static void luaStopServiceByName(string sServiceName)
		{
			try
			{
				ServiceController sc = new ServiceController(sServiceName);
				if (sc.Status.Equals(ServiceControllerStatus.Running))
				{
					sc.Stop();
					sc.Refresh();
				}
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaStopServiceByName " + ex.Message);
			}
		}

		public static IntPtr luaGetForegroundWindow()
		{
			return GetForegroundWindow();
		}

		public static int luaGetWindow(IntPtr hWnd, int wCmd)
		{
			return GetWindow(hWnd, wCmd);
		}

		public static string luaGetWindowText(IntPtr hWnd)
		{
			int length = GetWindowTextLength(hWnd);
			StringBuilder windowName = new StringBuilder(length + 1);
			GetWindowText(hWnd, windowName, windowName.Capacity);
			return windowName.ToString();
		}
	}
}
